/*
 * CVideoFrameFilter.cpp
 *
 *  Created on: 2016年1月1日
 *      Author: terry
 */

#include "CVideoFrameFilter.h"


namespace av
{

CVideoFrameFilter::CVideoFrameFilter():
		m_graph(),
		m_changed(false)
{
}

CVideoFrameFilter::~CVideoFrameFilter()
{
	close();
}

int CVideoFrameFilter::filter(AVFrame* inFrame, AVFrame* outFrame)
{
	if (!inFrame)
	{
		return EINVAL;
	}

	if (!outFrame)
	{
		return EINVAL;
	}

	if (m_changed)
	{
		m_changed = false;
		closeGraph();
	}

	int rc = 0;
	if (m_filters.empty())
	{
		rc = av_frame_ref(outFrame, inFrame);
	}
	else
	{
		rc = openGraph(inFrame);
		if (rc == 0)
		{
			rc = m_graph.filter(inFrame, outFrame);
		}
	}

	return rc;
}

int CVideoFrameFilter::open(const std::string& filters)
{
	return setFilter(filters);
}

void CVideoFrameFilter::close()
{
	m_graph.close();
}

bool CVideoFrameFilter::isOpen()
{
	return true;
}


int CVideoFrameFilter::setFilter(const std::string& filters)
{
	if (!checkFilter(filters))
	{
		return EINVAL;
	}

	m_filters = filters;
	m_changed = true;

	return 0;
}

bool CVideoFrameFilter::isActive()
{
	return !m_filters.empty();
}

bool CVideoFrameFilter::checkFilter(const std::string& filters)
{
	FilterGraph graph;
	int rc = graph.open(352, 288, AV_PIX_FMT_YUV420P, filters);
	graph.close();

	return (rc == 0);
}

int CVideoFrameFilter::openGraph(AVFrame* frame)
{
	if (m_graph.isOpen())
	{
		return 0;
	}

	int rc = m_graph.open(frame->width, frame->height, 
        (AVPixelFormat)frame->format, m_filters);
	return rc;
}

void CVideoFrameFilter::closeGraph()
{
	m_graph.close();
}




} /* namespace av */
